using System;
using System.Collections.Generic;

using Atomic.Libraries;
using Atomic.Libraries.Mathematics;
using Atomic.Libraries.Mathematics.Statistics;

namespace Atomic.Thermodynamics.StateEquations
{
	[Serializable]
	public class FittedBirchMurnaghan5 : BirchMurnaghan5, IFittedStateEquation
	{
		[NonSerialized] private RootMeanSquareStatistics fe, rfe;

		public FittedBirchMurnaghan5(double e0, double v0, double b0, double bp0, double bpp0, Vector x, IEnumerable<IVolumeEnergyPoint> points)
			: base(e0, v0, b0, bp0, bpp0, x)
		{
			FittingPoints = new ReadOnlyList<IVolumeEnergyPoint>(points);
		}

		private void ComputeFittingError()
		{
			if (fe != null && rfe != null)
			{
				// Already computed.
				return;
			}

			fe = new RootMeanSquareStatistics();
			rfe = new RootMeanSquareStatistics();

			foreach (IVolumeEnergyPoint p in FittingPoints)
			{
				double v = p.Volume;
				double e = p.Energy;
				fe.Add(Energy(v) - e);
				rfe.Add((Energy(v) - e) / e);
			}
		}
		
		public ReadOnlyList<IVolumeEnergyPoint> FittingPoints
		{
			get;
			private set;
		}

		IEnumerable<IVolumeEnergyPoint> IFittedStateEquation.FittingPoints
		{
			get
			{
				return FittingPoints;
			}
		}

		public double FittingError
		{
			get
			{
				ComputeFittingError();
				return fe.RootMeanSquare;
			}
		}

		public double RelativeFittingError
		{
			get
			{
				ComputeFittingError();
				return rfe.RootMeanSquare;
			}
		}
	}
}
